import { Service } from 'egg';
import * as blue from 'bluebird';
import * as _ from 'lodash';
// import * as Excel from 'exceljs';
import { ReadPreference } from 'mongodb';
const DB_ACCOUNT_PRODUCT = 'platform_account_product';
// const DB_ACCOUNT = 'platform_account';
const DB_CALL = '_c5_call_sheet';

// let reportCon = {};
// let reportConTemp = {};

// let reportLen = {};
// let reportLenTemp = {};

// let reportHour = {};
// let reportMonth = {};

// let time1;

type CALL_DOC = {
  _id: string;
  OFFERING_TIME: string;
  CALL_TIME_LENGTH: number;
  CALLED_NO: string;
  STATUS: string;
  datadb: string;
  account: string;
}

// const TypeStatus = {
//   dealing: 'dealing'
// }

// const TypeScope = {
//   t10: 't10',
//   t20: 't20',
//   t30: 't30',
//   t40: 't40',
//   t50: 't50',
//   t60: 't60',
//   tmax: 'tmax',
//   tno: 'tno',
// }

interface ReportType {
  account?: string;
  reportCon: any;
  reportLen: any;
  reportHour: any;
  reportMonth: any;
  reportConTemp?: any;
  reportLenTemp?: any;
}


let ans: {accountId: string, month: string, count: number, num: string}[] = [];

// const allAns: ReportType[] = [];

export default class SjCallService extends Service {
  
  /**
   * 2020年09月24日20:43:03 审计需求
   */
  public async sjcall() {
    // time1 = new Date().getTime();
    ans = [];
    const body = this.ctx.request.query;
    const startTime = body.startTime || '2020-08-01';
    const endTime = body.endTime || '2020-09-01';
    const accountId = body.accountId;
    const isoffline = body.isoffline;
    const concurrency = 1;

    if (!accountId) {
      return this.ctx.sendError('no accountid');
    }

    const query = {
      OFFERING_TIME: {
        $gte: startTime + ' 00:00:00',
        $lte: endTime + ' 00:00:00',
      },
      CONNECT_TYPE: 'dialout',
    };

    const accounts = await this.getAccounts(accountId);
    const all = accounts.length;

    let current = 0;
    // accounts = [{account: 'N00000001674', dataDB: 'cc_data_20161129'}];

    await blue.map(accounts, async(accountDoc) => {
      const accountId = accountDoc.account;
      const datadb = accountDoc.dataDB;
    
      const reportCon = {};
      const reportLen = {};
      const reportHour = {};
      const reportMonth = {};
      const reportConTemp = {};
      const reportLenTemp = {};

      const reportAll = {
        reportCon,
        reportLen,
        reportHour,
        reportMonth,
        reportConTemp,
        reportLenTemp,
      }

      this.app.logger.info('do_coun=' + accountId );

      const oneAll = await this.app.commonDB.db(datadb).collection(`${accountId}${DB_CALL}`).count();
      
      this.app.logger.info('do_count_res==' + accountId + ' ' + oneAll);
      if (oneAll === 0) {
        current++;
        return;
      }
      let oneCurrent = 0;

      let cursor;
      if (isoffline) {
        this.app.logger.info('offline_yes', accountId);

        cursor = await this.app.commonDB.db(datadb).collection(`${accountId}${DB_CALL}`).find(query, {fields: {
          OFFERING_TIME: 1,
          CALL_TIME_LENGTH: 1,
          CALLED_NO: 1,
          STATUS: 1,
          _id: 0,
        }}).setReadPreference(new ReadPreference('secondary',[{'offline': 'true'}])).batchSize(10000);
      } else {
        this.app.logger.info('offline_no', accountId);
        cursor = await this.app.commonDB.db(datadb).collection(`${accountId}${DB_CALL}`).find(query, {fields: {
          OFFERING_TIME: 1,
          CALL_TIME_LENGTH: 1,
          CALLED_NO: 1,
          STATUS: 1,
        }}).setReadPreference(ReadPreference.SECONDARY_PREFERRED).batchSize(10000);
      };
      
      let page = 1;
      let doc: CALL_DOC;
      // let hasDoc = false;
      while (await cursor.hasNext()) {
        // hasDoc = true;
        doc = await cursor.next();
        // this.ctx.logger.info('doc', doc.OFFERING_TIME);
        doc.datadb = datadb;
        doc.account = accountId;

        this.processOneCall(doc, reportAll);
        oneCurrent++;
        this.printOneRate(oneAll, oneCurrent, accountId, datadb, doc, page);
      }
      await this.processOneAccountEnd(accountId, reportAll);
      
      current++;
      this.printRate(all, current);

    }, {concurrency});
    this.app.logger.info('统计callPhone完成');
    this.ctx.setData(ans);
    this.ctx.sendSuccess();
  }

  public clearReportInMemory(reportAll) {
    reportAll.reportCon = {};
    reportAll.reportLen = {};
    reportAll.reportHour = {};
    reportAll.reportMonth = {};
    reportAll.reportConTemp = {};
    reportAll.reportLenTemp = {};
  }

  public async printRate(all: number, current: number) {
    if (current % 1 === 0) {
      this.app.logger.info('======account==rate======' + `${all} ${current} ${Math.round(current/all*100)}%`);
    }
  }

  public async printOneRate(all: number, current: number, accountId: string, datadb: string, doc: CALL_DOC, page: number) {
    if (current % 1000 === 0) {
      this.app.logger.info(`======${accountId}=${datadb}===rate==${doc.OFFERING_TIME} ${page} ${all} ${current} ${Math.round(current/all*100)}%`);
    }
  }

  public async processOneAccountEnd(accountId: string, reportall: ReportType, page?: number) {

    this.logger.info(accountId, page);

    const {reportConTemp, reportCon} = reportall;

    // this.logger.info('acount', account);
    // 处理report1
    Object.keys(reportConTemp).forEach((month) => {
      const dis = reportConTemp[month];
      if (!reportCon[month]) {
        reportCon[month] = {};
      }
      const one = reportCon[month];
      const arr = [2068, 2135, 14548, 14856, 14702, 14827, 14868, 15507, 17050, 18872, 20563, 14383];
      Object.keys(dis).forEach(num => {
        const count = dis[num];
        // this.app.logger.info(`calltop ${accountId} ${month} ${count} ${num}` );
        if (arr.indexOf(count) > -1) {
          this.app.logger.error(`calltop2 ${accountId} ${month} ${count} ${num}` );
          ans.push({
            accountId,
            month,
            count,
            num,
          });
        }
        if (!one[count]) {
          one[count] = 0;
        }
        one[count]++;
      });
    });
    // TODO: save to db 
    // allAns.push(reportall);
    delete reportall.reportConTemp;
    delete reportall.reportLenTemp;
  }

  public processOneCall(doc: CALL_DOC, reportall: ReportType) {
    const {reportConTemp} = reportall;
    // 1.DA5 手机号被呼叫集中度分析
    const reportConcentrate = (month: string, num: string) => {
      if(num.includes('.')) {
        return ;
      }
      if (!reportConTemp[month]) {
        reportConTemp[month] = {};
      }
      if (!reportConTemp[month][num]) {
        reportConTemp[month][num] = 0;
      }
      reportConTemp[month][num]++;
    }
    const month = this.getMonthFromTime(doc.OFFERING_TIME);

    const num = doc.CALLED_NO;
    if (num.includes('.')) {
      return ;
    }
    // 所有
    reportConcentrate(month, doc.CALLED_NO);
  }

  // "2020-08-18 16:02:26" => "202008"
  public getMonthFromTime(time: string): string {
    return time.substr(0, 4) + time.substr(5, 2);
  }

  public async getAccounts(accountId: string): Promise<{dataDB: string, account:string}[]> {
    const accounts = await this.app.commonDB.db('bill').collection(DB_ACCOUNT_PRODUCT)
      .find({product: 'cc', account: accountId, createTime: {$lt: '2020-09-01 00:00:00'}}, {fields: {_id: 1, dataDB:1, account:1}}).toArray();
    this.ctx.logger.info(accounts.length);
    return accounts as any;
  }

  // public async getDataDB(account) {
  //   let db = dbCache[account];
  //   if (!db) {
  //     const doc = await this.app.commonDB.db('bill').collection(DB_ACCOUNT_PRODUCT)
  //       .findOne({_id: account + '_cc'}, {fields: {dataDB:1}});
  //     if (!doc) {
  //       return null;
  //     }
  //     dbCache[account] = doc.dataDB;
  //     db = doc.dataDB;
  //   }
  //   return db;
  // }

}
